package com.hxzy.tms.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class HibernateBaseDao<T extends Serializable> extends HibernateDaoSupport implements BaseDao<T> {
    private Logger logger = LoggerFactory.getLogger(getClass());

    protected Class<? extends T> daoType;

    public HibernateBaseDao() {
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        daoType = (Class) pt.getActualTypeArguments()[0];
    }

    public T read(long id) {
        return (T) getSession().get(daoType, id);
    }

    public T create(T t) {
        getSession().save(t);
        return t;
    }

    public List<T> read(String hql, Map<String, Object> param) {
        Query query = getSession().createQuery(hql);
        for (Map.Entry<String, Object> p : param.entrySet()) {
            query.setParameter(p.getKey(), p.getValue());
        }
        return query.list();
    }

    public List<T> read(String hql, Params... params) {
        Query query = getSession().createQuery(hql);
        for (Params p : params) {
            query.setParameter(p.key, p.value);
        }
        return query.list();
    }

    public List<T> read(String hql, List<Params> params) {
        Query query = getSession().createQuery(hql);
        for (Params p : params) {
            query.setParameter(p.key, p.value);
        }
        return query.list();
    }

    public List<T> read(String hql, List<Params> params, int offset, int limit) {
        Query query = getSession().createQuery(hql);
        for (Params p : params) {
            query.setParameter(p.key, p.value);
        }
        query.setFirstResult(offset);
        query.setMaxResults(limit);

        return query.list();
    }

    public T read(Class<T> t, long id) {
        return (T) getSession().get(t, id);
    }

    public int update(T t) {
        try {
            getSession().update(t);
            return 1;
        } catch (HibernateException e) {
            logger.error("update exception: {}", e);
            return 0;
        }
    }

    public T merge(T t) {
        return (T) getSession().merge(t);
    }

    public int delete(T t) {
        try {
            getSession().delete(t);
            return 1;
        } catch (HibernateException e) {
            logger.error("delete exception: {}", e);
            return 0;
        }
    }

}
